package com.judge.rabbit;

import com.api.domain.dto.JudgeSubmitDTO;
import com.common.core.constants.RabbitMQConstants;
import com.judge.service.IJudgeService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Slf4j
@Component
public class JudgeConsumer {

    @Autowired
    private IJudgeService judgeService;

    @RabbitListener(queues = RabbitMQConstants.OJ_WORK_QUEUE, containerFactory = "rabbitListenerContainerFactory")
    public void consume(JudgeSubmitDTO judgeSubmitDTO) {
        try {
            // 验证消息有效性
            if (judgeSubmitDTO == null || judgeSubmitDTO.getUserId() == null || judgeSubmitDTO.getQuestionId() == null) {
                log.error("消息数据无效: {}", judgeSubmitDTO);
                return; // 无效消息直接丢弃
            }
            
            judgeService.doJudgeJavaCode(judgeSubmitDTO);
            
        } catch (Exception e) {
            log.error("处理消息失败: 用户ID={}, 题目ID={}, 错误信息: {}", 
                    judgeSubmitDTO != null ? judgeSubmitDTO.getUserId() : "unknown",
                    judgeSubmitDTO != null ? judgeSubmitDTO.getQuestionId() : "unknown",
                    e.getMessage(), e);
            
            // 细化异常处理策略
            handleException(judgeSubmitDTO, e);
        }
    }
    
    /**
     * 判断是否为业务逻辑错误
     * 业务逻辑错误包括：编译错误、运行错误、判题逻辑错误等
     * 这些错误不应该重试，因为重试也不会成功
     */
    private boolean isBusinessLogicError(Exception e) {
        String message = e.getMessage();
        if (message == null) {
            return false;
        }
        
        // 编译错误
        if (message.contains("编译") || message.contains("compile") || 
            message.contains("syntax") || message.contains("语法")) {
            return true;
        }
        
        // 运行错误
        if (message.contains("运行") || message.contains("runtime") || 
            message.contains("Exception") || message.contains("Error")) {
            return true;
        }
        
        // 判题逻辑错误
        if (message.contains("判题") || message.contains("judge") || 
            message.contains("测试用例") || message.contains("test case")) {
            return true;
        }
        
        return false;
    }
    
    /**
     * 细化异常处理策略
     */
    private void handleException(JudgeSubmitDTO judgeSubmitDTO, Exception e) {
        String errorType = classifyException(e);
        
        switch (errorType) {
            case "BUSINESS_ERROR":
                log.warn("业务逻辑错误，消息直接丢弃: {}", e.getMessage());
                // 业务错误不重试，可以考虑记录到失败表中
                break;
            case "SYSTEM_ERROR":
                log.error("系统错误，消息丢弃避免无限重试: {}", e.getMessage());
                // 系统错误可以考虑重试，但这里为了简化直接丢弃
                break;
            case "VALIDATION_ERROR":
                log.warn("数据验证错误，消息直接丢弃: {}", e.getMessage());
                break;
            default:
                log.error("未知错误类型，消息直接丢弃: {}", e.getMessage());
                break;
        }
    }
    
    /**
     * 对异常进行分类
     */
    private String classifyException(Exception e) {
        String message = e.getMessage();
        if (message == null) {
            return "UNKNOWN_ERROR";
        }
        
        // 数据验证错误
        if (message.contains("参数错误") || message.contains("数据无效") || 
            message.contains("Invalid") || message.contains("validation")) {
            return "VALIDATION_ERROR";
        }
        
        // 业务逻辑错误
        if (isBusinessLogicError(e)) {
            return "BUSINESS_ERROR";
        }
        
        // 系统级错误
        if (message.contains("Connection") || message.contains("连接") ||
            message.contains("Timeout") || message.contains("超时") ||
            message.contains("Network") || message.contains("网络")) {
            return "SYSTEM_ERROR";
        }
        
        return "UNKNOWN_ERROR";
    }
}
